	
package com.crawler.waf.security.services.impl;

import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;

import org.springframework.security.core.Authentication;
import org.springframework.util.Assert;

import com.crawler.waf.config.WafProperties;
import com.crawler.waf.security.authens.UserToken;
import com.crawler.waf.security.authentication.bearer.PreAuthenticatedBearerTokenAuthentication;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;

/**
 * bearer token 缓存验证类
 *
 */
public class UserCenterBearerTokenCacheService extends UserCenterBearerTokenService {

    private static LoadingCache<String, UserToken> bearerTokenCache;

    public static final String BEARER_TOKEN_CACHE_EXPIRE = "bearerToken.cache.expire";
    public static final String BEARER_TOKEN_CACHE_MAX_SIZE = "bearerToken.cache.maxSize";

    /**
     * 初始化bearerToken cache
     */
    private void initMacCache() {
        if (bearerTokenCache == null) {
            synchronized (this) {
                if (bearerTokenCache == null) {
                    bearerTokenCache = CacheBuilder.newBuilder()
                            .maximumSize(WafProperties.getPropertyForInteger(BEARER_TOKEN_CACHE_MAX_SIZE, "1000"))
                            .expireAfterWrite(WafProperties.getPropertyForInteger(BEARER_TOKEN_CACHE_EXPIRE, "1440"), TimeUnit.MINUTES)
                            .build(new CacheLoader<String, UserToken>() {
                                @Override
                                public UserToken load(String key) throws Exception {
                                    return invoke(key);
                                }
                            });
                }
            }
        }
    }

    /**
     * 调用父类获取UcCheckToken方法
     *
     * @param bearerToken
     * @return
     */
    private UserToken invoke(String bearerToken) {
        return super.verifyToken(new PreAuthenticatedBearerTokenAuthentication(bearerToken));
    }

    @Override
    public UserToken verifyToken(Authentication preAuthenticatedAuthentication) {
        Assert.notNull(preAuthenticatedAuthentication, "preAuthenticatedAuthentication");
        PreAuthenticatedBearerTokenAuthentication bearerTokenAuthentication = (PreAuthenticatedBearerTokenAuthentication) preAuthenticatedAuthentication;
        //初始化缓存实现
        this.initMacCache();
        UserToken ucCheckToken = null;
        try {
        	ucCheckToken = bearerTokenCache.get(bearerTokenAuthentication.getBearerToken());
        } catch (ExecutionException e) {
            throw new RuntimeException(e);
        }
        Assert.notNull(ucCheckToken, "ucCheckToken");
        if (ucCheckToken.getBearerToken().equalsIgnoreCase(bearerTokenAuthentication.getBearerToken())) {
            return ucCheckToken;
        }
        return null;
    }
}
